home *** CD-ROM | disk | FTP | other *** search
/ NeXTSTEP 3.3 (Developer)…68k, x86, SPARC, PA-RISC] / NeXTSTEP 3.3 Dev Intel.iso / NextDeveloper / Source / GNU / cctools / as / hppa-check.c < prev    next >
C/C++ Source or Header  |  1993-10-20  |  13KB  |  511 lines

  1. #include "hppa-opcode.h"
  2. #include <stdio.h>
  3.  
  4. extern long random();
  5.  
  6. #define RANGE(number)    (random() % (number))
  7. #define COIN            (RANGE(2))
  8. #define IMM_NUM(range)    {     int tmp000111000usv = RANGE(range); \
  9.                             if (tmp000111000usv == 0) \
  10.                                 printf(" %d", tmp000111000usv); \
  11.                             else \
  12.                                 printf(" %c%d", (COIN) ? '-' : ' ',  \
  13.                                     tmp000111000usv); \
  14.                         }
  15.  
  16.  
  17. /* The 'cond' decode table */
  18.  
  19. typedef  struct  condition_decode {
  20.     char condition[4];
  21. }  condT;
  22.  
  23. char *get_cond_str(const condT table[8][2], int c, int f );
  24.  
  25. /* condition decode tables
  26.  * Refer to PA-RISC 1.1 Architecture and Instruction Set 
  27.  * Reference Manual, Second edition, Sep. 1992, pp. 5-2 - 5-8.
  28.  */
  29.  
  30. /* Note : In all the following tables
  31.  *        ""   ... never
  32.  *        "???"   ... Invalid combination 
  33.  */
  34.  
  35. /* compare/subtraclt instruction conditions */
  36. const condT c_comp_sub[8][2]  = { /* Table 5-3 */
  37.     { "", "TR" },
  38.     { "=", "<>" },
  39.     { "<", ">=" },
  40.     { "<=", ">" },
  41.     { "<<", ">>=" },
  42.     { "<<=", ">>" },
  43.     { "SV", "NSV" },
  44.     { "OD", "EV" }
  45. };
  46.  
  47. /* add instruction conditions */
  48. const condT c_add[8][2]  = { /* Table 5-4 */
  49.     { "", "TR" },
  50.     { "=", "<>" },
  51.     { "<", ">=" },
  52.     { "<=", ">" },
  53.     { "NUV", "UV"  },
  54.     { "ZNV", "VNZ" },
  55.     { "SV", "NSV" },
  56.     { "OD", "EV" }
  57. };
  58.  
  59. /* logical instruction conditions */
  60. const condT c_logical[8][2]  = { /* Table 5-5 */
  61.     { "", "TR" },
  62.     { "=", "<>" },
  63.     { "<", ">=" },
  64.     { "<=", ">" },
  65.     { "???", "???" },
  66.     { "???", "???" },
  67.     { "???", "???" },
  68.     { "OD", "EV" }
  69. };
  70.  
  71. /* unit instruction conditions */
  72. const condT c_unit[8][2]  = { /* Table 5-6 */
  73.     { "", "TR" },
  74.     { "???", "???" },
  75.     { "SBZ", "NBZ" },
  76.     { "SHZ", "NHZ" },
  77.     { "SDC", "NDC" },
  78.     { "???", "???" },
  79.     { "SBC", "NBC" },
  80.     { "SHC", "NHC" }
  81. };
  82.  
  83. /* shift/extract/deposit instruction conditions */
  84. const condT c_shift_extract_deposit[8][2]  = { /* Table 5-7 */
  85.     { "", "???" },
  86.     { "=", "???" },
  87.     { "<", "???" },
  88.     { "OD", "???" },
  89.     { "TR", "???" },
  90.     { "<>", "???" },
  91.     { ">=", "???" },
  92.     { "EV", "???" }
  93. };
  94.  
  95.  
  96.  
  97. char *controlregs[] = { "fir", "psr", "epsr", "dirbase", "db", "fsr" };
  98. #define NCREGS    (sizeof controlregs / sizeof controlregs[0])
  99.  
  100. char *textlabels[] = { "foo", "bar", "baz", "xork" };
  101. #define NTLABELS    (sizeof textlabels / sizeof textlabels[0])
  102.  
  103. char *datalabels[] = { "data1", "data2", "data3", "data4" };
  104. #define NDLABELS    (sizeof datalabels / sizeof datalabels[0])
  105.  
  106. char *fp_cmp_cond[] =    {
  107.     "false?","false", "true?", "true", "!<=>", "!?>=", "!?<=",
  108.     "!<>", "!>=", "!?>", "?<=", "!<=", "!?<", "?>=", "!?=",
  109.     "!=t", "<=>", "=t", "?=", "?<", "<=", "!>", "?>", ">=",
  110.     "!<", "<>", "!=", "!?", "?", "=", "<", ">"
  111. };
  112. #define NFPCOND    (sizeof fp_cmp_cond / sizeof fp_cmp_cond[0])
  113.  
  114. char *fp_format_str[] = { "sgl", "dbl", "quad" };
  115. #define NFPFMT (sizeof fp_format_str / sizeof fp_format_str[0])
  116.  
  117. /*
  118.  * Traverse the opcode table, dumping out sample instructions.
  119.  */
  120. void
  121. main()
  122. {
  123.     int i;
  124.     const char *arg;
  125.     int do_not_nullify = 0;
  126.     
  127.     printf( "\t.text\n%s:", textlabels[0] );
  128.     /* a label at the begining of the file */
  129.     printf("label1:\n");
  130.     
  131.     for ( i = 0; i < NUMOPCODES; ++i )
  132.     {
  133.         if ( i == (NUMOPCODES/3) )
  134.             printf( "%s:", textlabels[1] );
  135.         if ( i == (NUMOPCODES/2) )
  136.             printf( "%s:", textlabels[2] );
  137.  
  138.         printf( "\t%s", pa_opcodes[i].name );
  139.         
  140.         for ( arg = pa_opcodes[i].args; *arg != '\0'; ++arg )
  141.         {
  142.             switch( *arg ) {
  143.  
  144.             case '\0':  /* end of args */
  145.                   break;
  146.  
  147.             case '(':   /* these must match exactly */
  148.                 putchar(' '); /* and FALLTHRU  */
  149.             case ')':
  150.             case ',':
  151.             case ' ':
  152.                 putchar(*arg);
  153.                   break;
  154.  
  155.             case 'b':   /* 5 bit register field at 10 */
  156.             case 'x':   /* 5 bit register field at 15 */
  157.              case 't':   /* 5 bit register field at 31 */
  158.             case 'v':   /* a 't' type extended to handle L/R register halves. */
  159.             case 'E':   /* a 'b' type extended to handle L/R register halves. */
  160.             case 'X':   /* an 'x' type extended to handle L/R register halves. */
  161.             case '4':   /* 5 bit register field at 10 (used in 'fmpyadd' and 'fmpysub') */
  162.             case '6':   /* 5 bit register field at 15 (used in 'fmpyadd' and 'fmpysub') */
  163.             case '7':   /* 5 bit register field at 31 (used in 'fmpyadd' and 'fmpysub') */
  164.             case '8':   /* 5 bit register field at 20 (used in 'fmpyadd' and 'fmpysub') */
  165.             case '9':   /* 5 bit register field at 25 (used in 'fmpyadd' and 'fmpysub') */
  166.                 printf(" %%r%d", RANGE(32));
  167.                  break;
  168.  
  169.             case 'r':   /* 5  bit immediate at 31 */
  170.             case 'R':   /* 5  bit immediate at 15 */
  171.                 printf(" %d", RANGE(32));
  172.                  break;
  173.             case 'T':   /* 5 bit field length at 31 (encoded as 32-T) */
  174.                 printf(" %d", RANGE(31) + 1);
  175.                  break;
  176.  
  177.             case '5':   /* 5 bit immediate at 15 */
  178.             case 'V':   /* 5  bit immediate at 31 */
  179.             case 'p':   /* 5 bit shift count at 26 (to support SHD instr.) */
  180.                         /* value is encoded in instr. as 31-p where p is   */
  181.                         /* the value scanned here */
  182.             case 'P':   /* 5-bit bit position at 26 */
  183.             case 'Q':   /* 5  bit immediate at 10 (unsigned bit position */
  184.                         /* value for the bb instruction) */
  185.                 IMM_NUM(15);
  186.                 continue;
  187.  
  188.             case 's':   /* 2 bit space identifier at 17 */
  189.                 printf(" %d", RANGE(4));
  190.                 break;
  191.  
  192.             case 'S':   /* 3 bit space identifier at 18 */
  193.                 printf(" %%sr%d", RANGE(8));
  194.                 break;
  195.  
  196.             case 'c':   /* indexed load completer. */
  197.             {
  198.                 int m, u, i;
  199.                 
  200.                 m = COIN;
  201.                 u = COIN;
  202.                 i = 0;
  203.                 if (COIN)
  204.                     while (i < 2) {
  205.                         if (m==1 && u==1) {
  206.                             printf(",sm");
  207.                             i++;
  208.                         }
  209.                         else if (m==1) 
  210.                             printf(",m");
  211.                             else if (u==1)
  212.                                 printf(",s");
  213.                                 else /* m==0 && u==0 */ {
  214.                                     printf(",sm");
  215.                                     i++;
  216.                                 } /* probability distribution */
  217.                         i++;
  218.                       }
  219.                   continue;
  220.             }
  221.             case 'C':   /* short load and store completer */
  222.                 if (COIN) 
  223.                     if (COIN)
  224.                         printf(",mb");
  225.                     else
  226.                         printf(",ma");
  227.                 continue;
  228.             case 'Y':   /* Store Bytes Short completer */
  229.             {
  230.                 int i = 0, m, a;
  231.                 while ( i < 2 ) {
  232.                     m = COIN;
  233.                     a = COIN;
  234.                 
  235.                     if (m==1) /* && (a==0 || a==1) */
  236.                         printf(",m");
  237.                     else if (a==0)  /* && m==0 */
  238.                         printf(",b");
  239.                         else if (a==1) /* && m==0 */
  240.                             printf(",e");
  241.                     i++;
  242.                 }
  243.                 continue;
  244.             }
  245.             case '<':   /* non-negated compare/subtract conditions. */
  246.             {
  247.                 int cmpltr;
  248.                 
  249.                 do {
  250.                     cmpltr = RANGE(4);
  251.                 } while (cmpltr == 0);
  252.                 
  253.                 printf(",%s", get_cond_str(c_comp_sub, cmpltr, 0));
  254.             }
  255.                 continue;
  256.             case '?':   /* negated or non-negated cmp/sub conditions. */
  257.                     /* used only by ``comb'' and ``comib'' pseudo-ops */
  258.             case '-':   /* compare/subtract conditions */
  259.             {
  260.                 int flag, cmpltr;
  261.                 char *tmp;
  262.                 
  263.                 do {
  264.                     flag = COIN;
  265.                     cmpltr = RANGE(8);
  266.                 } while ((flag & cmpltr) == 0 || (cmpltr == 0));
  267.                 
  268.                 tmp = get_cond_str(c_comp_sub, cmpltr, flag);                
  269.  
  270.                 if (*tmp != '\0')
  271.                     printf(",%s", tmp);
  272.             }
  273.                 continue;
  274.             case '+':   /* non-negated add conditions */
  275.             case '!':   /* negated or non-negated add conditions. */
  276.             {
  277.                 int flag, cmpltr;
  278.                 char *tmp;
  279.                 
  280.                 do {
  281.                     flag = COIN;
  282.                     cmpltr = RANGE(8);
  283.                 } while ((flag & cmpltr) == 0 || (cmpltr == 0));
  284.                 
  285.                 tmp = get_cond_str(c_add, cmpltr, flag);
  286.                 
  287.                 if (COIN && (*tmp != '\0')) /* condition */ {
  288.                         printf(",%s", tmp);
  289.                         if (COIN) { /* nullify */
  290.                             printf(",n ");
  291.                             do_not_nullify = 1;
  292.                         }
  293.                 }
  294.             }
  295.                 continue;        
  296.             case '&':   /* logical instruction conditions */
  297.             {
  298.                 int flag, cmpltr;
  299.                 char *tmp;
  300.                 
  301.                 flag = COIN;
  302.                 do {
  303.                     cmpltr = RANGE(8);
  304.                 } while (cmpltr == 4 || cmpltr == 5 || cmpltr == 6);
  305.                 
  306.                 tmp = get_cond_str(c_logical, cmpltr, flag);                
  307.  
  308.                 if (COIN && (*tmp != '\0')) /* condition */
  309.                     printf(",%s", tmp);
  310.             }
  311.                 continue;
  312.             case 'U':   /* unit instruction conditions */
  313.             {
  314.                 int flag, cmpltr;
  315.                 char *tmp;
  316.  
  317.                 flag = COIN;
  318.                 do {
  319.                     cmpltr = RANGE(8);
  320.                 } while (cmpltr == 1 || cmpltr == 5);
  321.                 
  322.                 tmp = get_cond_str(c_unit, cmpltr, flag);                
  323.                 if (COIN && (*tmp != '\0')) /* condition */
  324.                     printf(",%s", tmp);
  325.             }
  326.                 continue;
  327.             case '>':   /* shift/extract/deposit conditions. */
  328.             {
  329.                 int  cmpltr;
  330.                 char *tmp;
  331.                 
  332.                 cmpltr = RANGE(8);
  333.                 
  334.                 tmp = get_cond_str(c_shift_extract_deposit, cmpltr, 0);                
  335.  
  336.                 if (COIN && (*tmp != '\0')) /* condition */
  337.                     printf(",%s", tmp);
  338.             }
  339.                 continue;
  340.             case '~':   /* bvb,bb conditions */
  341.                 if (COIN)
  342.                     printf(",<");
  343.                 else
  344.                     printf(",>=");
  345.                 continue;
  346.                 
  347.             case 'i':   /* 11 bit immediate at 31 */
  348.                 IMM_NUM(1024);
  349.                 continue;
  350.                 
  351.             case 'j':   /* 14 bit immediate at 31 --- LO14 */
  352.             case 'a':    /* for be, ble --- BR17*/
  353.             {
  354.                 int field_selector = RANGE(3);
  355.                 switch (field_selector) {
  356.                 case 2:    /* field selector R`*/
  357.                     printf(" R`");
  358.                     break;
  359.                 case 1:    /* field selector L`*/
  360.                     printf(" L`");
  361.                     break;
  362.                 default:
  363.                     break;
  364.                 }
  365.                 IMM_NUM(8192);
  366.                 continue;
  367.             }  
  368.             case 'k':   /* 21 bit immediate at 31 --- HI21 */
  369.             {
  370.                 int field_selector = RANGE(3);
  371.                 switch (field_selector) {
  372.                 case 2:    /* field selector R`*/
  373.                     printf(" R`");
  374.                     break;
  375.                 case 1:    /* field selector L`*/
  376.                     printf(" L`");
  377.                     break;
  378.                 default:
  379.                     break;
  380.                 }
  381.                 IMM_NUM(1048576);
  382.                 continue;
  383.             }            
  384.             case 'n':   /* nullification for branch instructions */
  385.                 if (!do_not_nullify)
  386.                     if (COIN)
  387.                         printf(",n");
  388.                 else
  389.                     do_not_nullify = 0;
  390.                 continue;        
  391.             case 'w':   /* 12 bit branch displacement */
  392.                 IMM_NUM(2048);
  393.                 continue;
  394.             case 'W':   /* 17 bit branch displacement --- BL17 */
  395.             case '@':   /* 17 bit branch displacement --- JBSR */
  396.             case 'z':   /* 17 bit branch displacement (non-pc-relative) */
  397.                 IMM_NUM(65536);
  398.                 continue;
  399.             case 'B':   /* either "s,b" or "b" where b & s are defined above */
  400.                 if (COIN)
  401.                     printf(" %d,", RANGE(4));
  402.                 printf(" %%r%d", RANGE(32));
  403.                 break;
  404.             case 'A':   /* 13 bit immediate at 18 (to support BREAK instr.) */
  405.                 printf(" %d", RANGE(4096));
  406.                 continue;
  407.             case 'Z':   /* System Control Completer(for LDA, LHA, etc.) */
  408.                 if (COIN)
  409.                     printf(",M");
  410.                   continue;
  411.             case 'D':   /* 26 bit immediate at 31 (to support DIAG instr.) */
  412.                           /* the action (and interpretation of this operand is
  413.                              implementation dependent) */
  414.                 IMM_NUM(33554432);
  415.                   continue;
  416.             case 'f':   /* 3 bit Special Function Unit (SFU) identifier at 25 */
  417.             case 'u':   /* 3 bit coprocessor unit identifier at 25 */
  418.                 printf("%d", RANGE(8));
  419.                   continue;
  420.             case 'O':   /* 20 bit SFU op. split between 15 bits at 20 and 5 bits at 31 */
  421.                 printf("%d", RANGE(1048576));
  422.                   continue;
  423.             case 'o':   /* 15 bit Special Function Unit operation at 20 */
  424.             case '1':   /* 15 bit SFU op. split between 10 bits at 20
  425.                                and 5 bits at 31 */
  426.                 printf("%d", RANGE(32768));
  427.                   continue;
  428.             case '2':   /* 22 bit SFU op. split between 17 bits at 20
  429.                                and 5 bits at 31 */
  430.                 printf("%d", RANGE(4194304));
  431.                   continue;
  432.             case '0':   /* 10 bit SFU op. split between 5 bits at 20
  433.                                and 5 bits at 31 */
  434.                 printf("%d", RANGE(1024));
  435.                   continue;
  436.             case 'G':   /* Destination FP Operand Format Completer (2 bits at 18) */
  437.             case 'F':   /* Source FP Operand Format Completer (2 bits at 20) */
  438.                 printf(",%s", fp_format_str[RANGE(NFPFMT)]);
  439.                   continue;
  440.             case 'M':   /* FP Compare Conditions (encoded as 5 bits at 31) */
  441.                 printf(",%s", fp_cmp_cond[RANGE(NFPCOND)]);
  442.                   continue;
  443.  
  444. #if 0
  445.             case 'H':  /* Floating Point Operand Format at 26 for       */
  446.                         /* 'fmpyadd' and 'fmpysub' (very similar to 'F') */
  447.                         /* bits are switched from other FP Operand       */
  448.                         /* formats. 1=SGL, 1=<none>, 0=DBL               */
  449.                 f = pa_parse_fp_format(&s);
  450.                 switch (f) {
  451.                 case SGL:
  452.                     opcode |= 0x20;
  453.                 case DBL:
  454.                     the_insn.fpof1 = f;
  455.                     continue;
  456.  
  457.                 case QUAD:
  458.                 case ILLEGAL_FMT:
  459.                 default:
  460.                     as_bad("Illegal Floating Point Operand Format for"
  461.                         "this instruction: '%s'",*s);
  462.                 }
  463.                 break;
  464.             default:
  465.                 abort();
  466. #endif    /* 0 */
  467.  
  468.             }
  469.         }
  470.         putchar( '\n' );
  471.     }
  472.     /* a label at the end of the file */
  473.     printf("label2:\n");
  474.     
  475.  
  476.     printf( "%s:\n", textlabels[3] );
  477.     printf( "\t.data\n" );
  478.     printf( "data1:    .space 1024\n" );
  479.     printf( "data2:    .space 1024\n" );
  480.     printf( "data3:    .space 1024\n" );
  481.     printf( "data4:    .space 1024\n" );
  482.  
  483. }
  484.  
  485. /* The function to search the condition decode table 
  486.  * and return the 'cond'
  487.  * The way tables are initialised ... NULL termination 
  488.  * of 'cond' is assured.
  489.  */ 
  490. char *get_cond_str(const condT table[8][2], int c, int f )
  491. {
  492.  
  493. /* do range check and return NULL if out of bound */
  494. /*    char *str;
  495.     if ( c < 0  || c > 7 )
  496.         *str = (char *) NULL;
  497.     else    if ( f < 0  || f > 1 )
  498.         *str = (char *) NULL;
  499.     else 
  500.         str = table[c][f].condition;
  501.  
  502.     return str;
  503. */
  504.  
  505. /* here goes the one liner */
  506.  
  507.     return (c<0 || c>7 || f<0 || f>1)
  508.         ? (char *)NULL : table[c][f].condition    ;
  509. }    /* end get_cond_str() */
  510.  
  511.